package org.nahtanoj.contacts;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.logging.Logger;

public class ContactStoreFile implements ContactStore {

	private HashMap<String, Contact> contacts;
	private final String user;
	private HashMap<String, Contact> matched;
	private HashMap<String, Contact> newDocs;
	private HashMap<String, Contact> newMail;
	private static final Logger log = Logger.getLogger(ContactStoreFile.class.getName());

	public ContactStoreFile(String user) {
		this.user = user;
	}

	@Override
	public void add(Contact c) {
		//		c.hashUpdate();
		if (this.contacts.containsKey(c.hashCalc())) {
			//TODO should we migrate this to ContactStoreMail and ContactStoreDocs
			log.warning("Duplicate hash:" + c + " dropping likely duplicate"); // Probably means the row is identical - unless hash calc collision
			//this.contacts.put(c.hashCalc() + System.currentTimeMillis(), c);
			//TODO to drop this we need to add to drop list - we can't drop from docs though?
		} else {
			//			System.out.println(c.hashCalc());
			this.contacts.put(c.hashCalc(), c);
		}
	}

	@Override
	public void drop(Contact c) {
		//		if (this.getContacts().containsKey(c.hashCalc())) {
		//			this.getContacts().remove(c.hashCalc());
		//		} else {
		//			log.warning("Unable to drop:");
		//		}
		String hash = null;
		for (String h : this.contacts.keySet()) {
			if (this.contacts.get(h).equals(c)) {
				if (hash == null) {
					hash = h;
				} else {
					log.warning("Duplicate contact found with same hash:");
				}
			}
		}
		if (hash != null) {
			this.getContacts().remove(hash);
		} else {
			log.warning("Unable to drop:");
		}
	}

	/* (non-Javadoc)
	 * @see org.nahtanoj.contacts.ContactStore#getContacts()
	 */
	@Override
	public HashMap<String, Contact> getContacts() {
		return this.contacts;
	}

	@Override
	public HashMap<String, Contact> getMatched() {
		return this.matched;
	}

	@Override
	public HashMap<String, Contact> getNewDocs() {
		return this.newDocs;
	}

	@Override
	public HashMap<String, Contact> getNewMail() {
		return this.newMail;
	}

	/* (non-Javadoc)
	 * @see org.nahtanoj.contacts.ContactStore#loadContacts()
	 */
	@Override
	public void load() {
		this.contacts = new HashMap<String, Contact>();
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(this.user + ".csv")));
			String line = br.readLine(); // Skip header
			if (line.startsWith("\"")) {
				int i = 1;
				while ((line = br.readLine()) != null) {
					while (!line.endsWith("\"")) {
						line += br.readLine();
					}
					line = line.substring(1,  line.length() - 1);
					String a[] = line.split("\",\"", -1);
					if (line.split("\",\"", -1).length != 22) {
						System.out.println(line);
					}
					Contact c = new Contact(line.split("\",\"", -1), i++);
					add(c);
				}
			} else {
				int i = 1;
				while ((line = br.readLine()) != null) {
					Contact c = new Contact(line.split(",", -1), i++);
					add(c);
				}
			}
			br.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/* (non-Javadoc)
	 * @see org.nahtanoj.contacts.ContactStore#saveContacts()
	 */
	@Override
	public void save() {
		try {
			FileWriter fw = new FileWriter(this.user + ".csv");
			fw.write("Last Name,First Name,Business,Home,Mobile,Mobile 2,E-mail Address,E-mail 2 Address,Home Street,Home Street 2,Home City,Home State,Home Postal Code,Home Country,Birthday,Anniversary,Category,Children,Notes,ContactSync,Hash,Validation\n");
			for (Contact c : this.contacts.values()) {
				c.hashUpdate();
				fw.write(c.getLastName());		fw.write(",");
				fw.write(c.getFirstName());		fw.write(",");
				fw.write(c.getBusiness());		fw.write(",");
				fw.write(c.getHome());			fw.write(",");
				fw.write(c.getMobile());		fw.write(",");
				fw.write(c.getMobile2());		fw.write(",");
				fw.write(c.getEmailAddress());	fw.write(",");
				fw.write(c.getEmail2Address());	fw.write(",");
				fw.write(c.getHomeStreet());	fw.write(",");
				fw.write(c.getHomeStreet2());	fw.write(",");
				fw.write(c.getHomeCity());		fw.write(",");
				fw.write(c.getHomeState());		fw.write(",");
				fw.write(c.getHomePostalCode());fw.write(",");
				fw.write(c.getHomeCountry());	fw.write(",");
				fw.write(c.getBirthday());		fw.write(",");
				fw.write(c.getAnniversary());	fw.write(",");
				fw.write(c.getCategory());		fw.write(",");
				fw.write(c.getChildren());		fw.write(",");
				fw.write(c.getNotes());			fw.write(",");
				fw.write(c.getContactSync());	fw.write(",");
				fw.write(c.getHash());			fw.write(",");
				fw.write(c.getValidation());	fw.write("\n");
			}
			fw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void setMatches(HashMap<String, Contact> ms,
			HashMap<String, Contact> ud, HashMap<String, Contact> us) {
		this.matched = ms;
		this.newDocs = ud;
		this.newMail = us;
	}
}
